// Fill out your copyright notice in the Description page of Project Settings.


#include "PlayerStateBaseCpp.h"
#include "GameInstanceBaseCpp.h"
#include "AttackComponentBaseCpp.h"
#include "ItemCombinationTable.h"
#include "GameModeBaseCpp.h"

APlayerStateBaseCpp::APlayerStateBaseCpp()
{
	CurrentMapReward = 0;
	ReadCombinationTableFromFile();
	Power = 100.0f;
}


void APlayerStateBaseCpp::AddReword()
{
	CurrentMapReward++;
}

int APlayerStateBaseCpp::GetReward() const
{
	return CurrentMapReward;
}

TMap<EItemType, FCollectableItemStruct>* APlayerStateBaseCpp::GetItemsMap()
{
	return &ItemsMap;
}

int APlayerStateBaseCpp::GetItemCntFromItemsMap(const EItemType Type) const
{
	return ItemsMap[Type].GetCnt();
}

bool APlayerStateBaseCpp::RemoveItemFromItemsMap(const EItemType Type, const int NeedRemoveAmount)
{
	if (ItemsMap.Contains(Type))
	{
		if (ItemsMap[Type].GetCnt() - NeedRemoveAmount > 0)
		{
			ItemsMap[Type].RemoveCnt(NeedRemoveAmount);
			return true;
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("The Item will be removed"));
			ItemsMap.Remove(Type);
			return false;
		}
	}
	return false;
}

void APlayerStateBaseCpp::AddItemToItemsMap(const EItemType Type, const int NeedAddAmount)
{
	if (ItemsMap.Contains(Type))
	{
		ItemsMap[Type].AddCnt(NeedAddAmount);
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("ItemsMap does not have key, now try to make a new key..."));
		const FCollectableItemStruct NewItem(FString(""), Type, NeedAddAmount);
		ItemsMap.Add(Type, NewItem);
	}
}


void APlayerStateBaseCpp::ReadCombinationTableFromFile()
{
	if (CombinationTable != nullptr)
	{
		return;
	}
	CombinationTable = LoadObject<UDataTable>(nullptr, TEXT("/Game/DataConfig/ItemCombinationTable.ItemCombinationTable"));
	if (CombinationTable == nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("path wrong"));
		return;
	}
	for (auto RowIt = CombinationTable->GetRowMap().CreateConstIterator(); RowIt; ++RowIt)
	{
		FItemCombinationTable* TableRowValue = (FItemCombinationTable*)RowIt->Value;
		if (TableRowValue == nullptr)
		{
			UE_LOG(LogTemp, Error, TEXT("cast wrong"));
			return;
		}
		FCombinationStruct CS(TableRowValue->TargetItemType, TableRowValue->NeedAmount);
		CombinationMap.Add(TableRowValue->SourceItemType, CS);
	}
}

bool APlayerStateBaseCpp::GetCombinationMap(const EItemType& SrcType, EItemType& TgtType, int& Amount) const
{
	if (CombinationMap.Contains(SrcType))
	{
		CombinationMap[SrcType].GetCombination(TgtType, Amount);
		return true;
	}
	return false;
}

bool APlayerStateBaseCpp::HasCombination(const EItemType& SrcType) const
{
	if (CombinationMap.Contains(SrcType))
	{
		return true;
	}
	return false;
}

float APlayerStateBaseCpp::GetPlayerHP() const
{
	return PlayerHP;
}

void APlayerStateBaseCpp::IncreasePlayerHP(const float Up)
{
	PlayerHP += Up;
}

void APlayerStateBaseCpp::DecreasePlayerHP(const float Down)
{
	PlayerHP -= Down;
}

void APlayerStateBaseCpp::SetPlayerHP(const float AbsHP)
{
	PlayerHP = AbsHP;
}

void APlayerStateBaseCpp::SetBaseDamage(const float BaseValue)
{
	BaseDamage = BaseValue;
}

void APlayerStateBaseCpp::SetProDamage(const float ProValue)
{
	ProDamage = ProValue;
}

void APlayerStateBaseCpp::SetDamage()
{
	AGameModeBaseCpp* CurrentGameMode = Cast<AGameModeBaseCpp>(UGameplayStatics::GetGameMode(GetWorld()));
	CurrentGameMode->GetPawnDamageMap(EPawnType::E_Player, EAttackMode::E_BasicAttack, BaseDamage);
	CurrentGameMode->GetPawnDamageMap(EPawnType::E_Player, EAttackMode::E_ProAttack, ProDamage);
}


float APlayerStateBaseCpp::GetBaseDamage() const
{
	return BaseDamage;
}

float APlayerStateBaseCpp::GetProDamage() const
{
	return ProDamage;
}

float APlayerStateBaseCpp::GetPower() const
{
	return Power;
}

void APlayerStateBaseCpp::IncreasePower(const float DeltaValue)
{
	if (Power < 100.0f)
	{
		Power += DeltaValue;
	}
	else
	{
		Power = 100.0f;
	}
}

void APlayerStateBaseCpp::DecreasePower(const float DeltaValue)
{
	if (Power > 0.0)
	{
		Power -= DeltaValue;
	}
	else
	{
		Power = 0.0f;
	}
}

float APlayerStateBaseCpp::GetPowerIncreasingSpeed() const
{
	return PowerIncreasingSpeed;
}

float APlayerStateBaseCpp::GetPowerDecreasingSpeed() const
{
	return PowerDecreasingSpeed;
}

void APlayerStateBaseCpp::InitItemMapFromGameInstance()
{
	UGameInstanceBaseCpp* CurrentGameInstance = Cast<UGameInstanceBaseCpp>(GetGameInstance());
	TMap<EItemType, FCollectableItemStruct> ItemMapFromGameInstance;
	CurrentGameInstance->LoadGameByGameSaver();
	CurrentGameInstance->GetItemMap(ItemMapFromGameInstance);
	ItemsMap.Reset();
	for (const auto E : ItemMapFromGameInstance)
	{
		FCollectableItemStruct FS(E.Value);
		ItemsMap.Add(E.Key, FS);
	}
	ItemMapFromGameInstance.Reset();
	CurrentGameInstance->ClearItemMap();
}

